#include "utils/config.h"
#include <fstream>
#include <sstream>
#include <algorithm>
#include <cctype>

using namespace std;

bool Config::load(const string& filename) {
    ifstream file(filename);
    if (!file.is_open()) {
        return false;
    }

    string line;
    while (getline(file, line)) {
        // 移除注释和空白
        line = line.substr(0, line.find(';'));
        line = line.substr(0, line.find('#'));
        line.erase(remove_if(line.begin(), line.end(), ::isspace), line.end());

        if (line.empty()) continue;

        size_t delimiter = line.find('=');
        if (delimiter != string::npos) {
            string key = line.substr(0, delimiter);
            string value = line.substr(delimiter + 1);
            m_config[key] = value;
        }
    }

    return true;
}

string Config::getString(const string& key, const string& defaultValue) const {
    auto it = m_config.find(key);
    return it != m_config.end() ? it->second : defaultValue;
}

int Config::getInt(const string& key, int defaultValue) const {
    try {
        return stoi(getString(key, to_string(defaultValue)));
    } catch (...) {
        return defaultValue;
    }
}

double Config::getDouble(const string& key, double defaultValue) const {
    try {
        return stod(getString(key, to_string(defaultValue)));
    } catch (...) {
        return defaultValue;
    }
}

bool Config::getBool(const string& key, bool defaultValue) const {
    string val = getString(key, defaultValue ? "true" : "false");
    transform(val.begin(), val.end(), val.begin(), ::tolower);
    return val == "true" || val == "1";
}

Config::TradingParams Config::getTradingParams() const {
    TradingParams params;
    params.symbol = getString("trading.symbol", "BTCUSDT");
    params.tick_size = getDouble("trading.tick_size", 0.01);
    params.lot_size = getInt("trading.lot_size", 1);
    params.max_position = getDouble("trading.max_position", 100);
    return params;
}

Config::RiskParams Config::getRiskParams() const {
    RiskParams params;
    params.max_drawdown = getDouble("risk.max_drawdown", 0.05);
    params.max_daily_loss = getDouble("risk.max_daily_loss", 10000);
    params.max_order_value = getDouble("risk.max_order_value", 5000);
    return params;
}